package com.wyiot.pet.service;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wyiot.core.exception.ValidateException;
import com.wyiot.core.enums.MessageTypeEnum;
import com.wyiot.core.enums.OrderStatusEnum;
import com.wyiot.core.enums.WaybillStatusEnum;
import com.wyiot.pet.mapper.*;
import com.wyiot.pet.model.dto.LogisticsInfoDTO;
import com.wyiot.pet.model.dto.OrderDTO;
import com.wyiot.pet.model.dto.WayBillDTO;
import com.wyiot.pet.model.entity.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
 * 工作人员Service
 *
 * @author yly
 * @since 2022年04月06日
 */
@Service
public class WorkerService extends ServiceImpl<WorkerMapper, WorkerDO> {
    @Resource
    WayBillService wayBillService;
    @Resource
    OrderService orderService;
    @Resource
    UserMapper userMapper;
    @Resource
    BoxService boxService;
    @Resource
    UserMessageService userMessageService;
    @Resource
    WaybillMessageService waybillMessageService;

    /**
     * 绑定运输箱
     *
     * @see WayBillDTO
     */
    @Transactional(rollbackFor = Exception.class)
    public void bindingBox(WayBillDTO wayBillDTO) {
        BoxDO box = boxService.getOne(Wrappers.lambdaQuery(BoxDO.class).eq(BoxDO::getBoxNumber, wayBillDTO.getBoxNumber()));
        if (box.isIfWorking()){
            throw ValidateException.of("绑定失败");
        }
        box.setIfWorking(true);
        /*跟新运单表*/
        wayBillService.update(Wrappers.lambdaUpdate(WayBillDO.class)
                .eq(WayBillDO::getWayBillId, wayBillDTO.getWayBillId()).set(WayBillDO::getBoxId, box.getBoxId()));
        /*跟新box表*/
        boxService.updateById(box);
    }

    /**
     * 上门取件
     *
     * @see OrderDTO
     */
    @Transactional(rollbackFor = Exception.class)
    public void isTakeCodeTrue(OrderDTO orderDTO) {
        List<WayBillDO> wayBillDOS = orderService.queryWayBillByOrderId(orderDTO.getOrderId());
        List<WayBillDO> haveBoxPets = new ArrayList<>();
        /*具有运输箱号的宠物*/
        for (WayBillDO wp : wayBillDOS) {
            if (wp.getBoxId() != null) {
                haveBoxPets.add(wp);
            }
        }
        /*上门取件员是否为该订单的取件员*/
        OrderDO order = orderService.getById(orderDTO.getOrderId());
        if (!orderDTO.getOrderTakeMan().equals(order.getOrderTakeMan())
                || !order.getOrderState().equals(OrderStatusEnum.WaitForTook)) {
            throw ValidateException.of("操作失败");
        } else if (wayBillDOS.size() > haveBoxPets.size()) {
            throw ValidateException.of("请先为宠物绑定运输箱");
        }
        if (order.getTakeCode() != orderDTO.getTakeCode()) {
            throw ValidateException.of("验证码错误");
        }
        /*改变订单状态为运输中*/
        order.setOrderState(OrderStatusEnum.WaitForSign);
        orderService.updateById(order);
        /*生成运单日志信息  （XX网点揽件员XXX已揽件……）*/
        List<WayBillMessageDO> wbMessageList = new ArrayList<>();
        WorkerDO worker = getById(orderDTO.getOrderTakeMan());
        for (WayBillDO wb : wayBillDOS) {
            wb.setWayBillNumber();
            wb.setWayBillState(WaybillStatusEnum.Taken);
            wb.setDepartTime(new Date());
            /*产生已取件消息*/
            wbMessageList.add(new WayBillMessageDO(
                    wb.getWayBillId(), order.getOrderTransportation(), worker.getWorkerId(),
                    worker.getWorkerName(), worker.getWorkerPhone(), worker.getWorkArea(), WaybillStatusEnum.Taken));
        }
        waybillMessageService.saveBatch(wbMessageList);
        wayBillService.updateBatchById(wayBillDOS);
    }

    /**
     * 填写物流信息
     *
     * @see LogisticsInfoDTO
     */
    @Transactional(rollbackFor = Exception.class)
    public void fillLogisticsInfo(LogisticsInfoDTO logisticsInfoDTO) {
        WorkerDO worker = getById(logisticsInfoDTO.getWorkerId());
        OrderDO orderDO = orderService.getById(logisticsInfoDTO.getOrderId());
        UserDO user = userMapper.getUserIdByUserPhone(orderDO.getReceiverPhone());
        BeanUtils.copyProperties(logisticsInfoDTO, orderDO);
        /*发送消息给用户，你的宠物已上车*/
        userMessageService.save(new UserMessageDO(user.getUserId(),user.getUserCode(),
                orderDO.getOrderNumber(), false, MessageTypeEnum.ReceiptMessage, logisticsInfoDTO.getExpectedDeliveryTime()
        ));
        /*跟新运单状态为运输中*/
        List<WayBillDO> wayBillDOS = orderService.queryWayBillByOrderId(logisticsInfoDTO.getOrderId());
        /*产生运输中消息 （快递已到达……，已将宠物送上……）*/
        List<WayBillMessageDO> wayBillMessageDOS = new ArrayList<>();
        for (WayBillDO wb : wayBillDOS) {
            wayBillMessageDOS.add(new WayBillMessageDO(wb.getWayBillId(),orderDO.getOrderTransportation(),
                    logisticsInfoDTO.getCarNumber(), worker.getWorkerId(), worker.getWorkerName(),
                    worker.getWorkArea(), logisticsInfoDTO.getDepartureStation(),
                    logisticsInfoDTO.getDestination(), WaybillStatusEnum.Transporting));
            wb.setWayBillState(WaybillStatusEnum.Transporting);
        }
        waybillMessageService.saveBatch(wayBillMessageDOS);
        wayBillService.updateBatchById(wayBillDOS);
        orderService.updateById(orderDO);
    }

}
